#========================================================================
#				DirectionController
#========================================================================
# 【方向控制器】
# 控制父节点面向对应位置方向
#========================================================================
# @datetime: 2020-12-26 19:17 => 0.1
# @datetime: 2021-9-12 13:45 => 1.0
# @Godot version: 3.2.4
#========================================================================

extends TextureRect

## 旋转速度
export var rotation_speed : float = 5.0
## 偏移的角度（决定贴图方向）（默认顶部朝向目标位置）
export (float, -180, 180) var offset_degress : float = 0.0 setget set_offset_degress


# 当前控制的宿主
onready var host : Node2D = get_parent()		# 控制的宿主
# 偏移的弧度
onready var _offset_rot : float = deg2rad(offset_degress)



#==================================================
#   Set/Get
#==================================================
func set_offset_degress(value: float) -> void:
	offset_degress = value
	_offset_rot = deg2rad(offset_degress)



#==================================================
#   内置方法
#==================================================
func _physics_process(delta: float) -> void:
	var target_pos = get_global_mouse_position()		# 目标位置（这里我设置为鼠标的位置）
	var currect_pos = host.global_position				# 当前位置
	turn_to(currect_pos, target_pos, delta)



#==================================================
#   自定义方法
#==================================================
##  转向到目标位置 
## @from  角色位置
## @to  目标位置
## @delta  帧速率
func turn_to(from: Vector2, to: Vector2, delta: float) -> void:
	# 自身到目标的方向
	var dir = to.direction_to(from)
	# 弧度方向
	#（站立的时候，人物头部是朝向上面的，所以为 Vector2.UP）
	# 但这样造成旋转的值多了 PI/2，所以减去，加上用户设置的偏移的弧度
	var rot_dir = Vector2.UP.rotated(host.global_rotation - PI/2 + _offset_rot)
	# [面向角度]与[自身当前旋转角度]的点积
	var dot = dir.dot(rot_dir)
	
	# 旋转速度
	var r_speed = rotation_speed * delta
	# 旋转的值
	var v = sign(dot) * r_speed
	
	if (
		# 点积大小超过 rotation_speed 则进行旋转
		# 防止速度过快时的抖动问题
		abs(dot) > r_speed
		
		# 自身面向角度 和 自身到目标点的角度 不是在自身的背面
		# 有时在背面的 dot 值也会为 0，防止在这个时候突然转向到后面
		|| fmod(abs(dir.angle() - host.global_rotation), PI) > PI/2+0.01
	):
		host.rotate(v)
		
	else:
		host.global_rotation = dir.angle() - PI/2 - _offset_rot

